package com.alogic.xscript.addons;

import com.alogic.sda.SDAFactory;
import com.alogic.sda.SecretDataArea;
import com.alogic.xscript.AbstractLogiclet;
import com.alogic.xscript.ExecuteWatcher;
import com.alogic.xscript.Logiclet;
import com.alogic.xscript.LogicletContext;
import com.alogic.xscript.doc.XsObject;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import com.anysoft.util.code.Coder;
import com.anysoft.util.code.CoderFactory;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.mail.HtmlEmail;

/**
 * 发送邮件
 */
public class Mail extends AbstractLogiclet {
    protected String smtpHostname = "${email.hostname}";
    protected String smtpUsername = "${email.username}";
    protected String smtpPassword = "${email.password}";
    protected int smtpPort = 25;
    protected String smtpFrom = "${email.from}";
    protected String $to = "";
    protected String $content = "";
    protected String $subject = "";
    protected String encoding = "${http.encoding}";
    protected String sdaId = "";
    protected String codeId = "$mail.code";
    protected String reasonId = "$mail.reason";
    protected boolean sslEnable = false;
    protected String sslPort = "465";

    protected Coder coder = null;

    public Mail(String tag, Logiclet p) {
        super(tag, p);
    }

    @Override
    public void configure(Properties p) {
        super.configure(p);

        sdaId = PropertiesConstants.getString(p, "sda", sdaId, true);
        smtpHostname = PropertiesConstants.getString(p, "hostname", smtpHostname, true);
        smtpUsername = PropertiesConstants.getString(p, "username", smtpUsername, true);
        smtpPassword = PropertiesConstants.getString(p, "password", smtpPassword, true);
        smtpPort = PropertiesConstants.getInt(p, "password", smtpPort, true);
        encoding = PropertiesConstants.getString(p, "encoding", encoding, true);
        smtpFrom = PropertiesConstants.getString(p, "from", smtpFrom, true);
        $to = PropertiesConstants.getRaw(p, "to", "");
        $subject = PropertiesConstants.getRaw(p, "subject", "");
        $content = PropertiesConstants.getRaw(p, "content", "");
        codeId = PropertiesConstants.getString(p,"codeId",codeId);
        reasonId = PropertiesConstants.getString(p,"reasonId",reasonId);

        sslEnable = PropertiesConstants.getBoolean(p,"sslEnable",sslEnable);
        sslPort = PropertiesConstants.getString(p,"sslPort",sslPort);
        try {
            coder = CoderFactory.newCoder(PropertiesConstants.getString(p,"coder","DES3"));
        }catch (Exception ex){
            log(ExceptionUtils.getStackTrace(ex),LOG_ERROR);
        }
    }

    @Override
    protected void onExecute(XsObject root, XsObject current, LogicletContext ctx, ExecuteWatcher watcher) {
        String subject = PropertiesConstants.transform(ctx, $subject, "");
        String content = PropertiesConstants.transform(ctx, $content, "");
        String to = PropertiesConstants.transform(ctx, $to, "");

        if (StringUtils.isEmpty(to)){
            log("Failed to send email,the destination is null", "error");
            ctx.SetValue(codeId,"failed");
            ctx.SetValue(reasonId,"邮件地址为空");
            return ;
        }

        if (StringUtils.isEmpty(subject)){
            log("Failed to send email,the subject is null", "error");
            ctx.SetValue(codeId,"failed");
            ctx.SetValue(reasonId,"邮件标题为空");
            return ;
        }

        if (StringUtils.isEmpty(content)){
            log("Failed to send email,the content is null", "error");
            ctx.SetValue(codeId,"failed");
            ctx.SetValue(reasonId,"邮件内容为空");
            return ;
        }

        String hostname = null;
        String username = null;
        String password = null;
        String from = null;
        boolean sslSupport = sslEnable;
        String sslSmtpPort = sslPort;
        int port = smtpPort;

        if (StringUtils.isNotEmpty(sdaId)){
            SecretDataArea sda = SDAFactory.getDefault().load(sdaId, true);
            if (sda != null){
                hostname = sda.getField("host", hostname);
                username = sda.getField("username", username);
                password = sda.getField("password", password);
                from = sda.getField("from", from);
                sslSupport = sda.getField("sslEnable",sslSupport);
                sslSmtpPort = sda.getField("sslPort",sslSmtpPort);
                port = sda.getField("port",port);
                log("from=" + from);
            }else{
                hostname = smtpHostname;
                username = smtpUsername;
                if (coder != null){
                    password = coder.decode(smtpPassword, username);
                }else{
                    password = smtpPassword;
                }
                from = smtpFrom;
                log("smtpFrom=" + smtpFrom);
            }
        }else{
            hostname = smtpHostname;
            username = smtpUsername;
            if (coder != null){
                password = coder.decode(smtpPassword, username);
            }else{
                password = smtpPassword;
            }
            from = smtpFrom;
            log("smtpFrom=" + smtpFrom);
        }

        HtmlEmail htmlEmail = new HtmlEmail();
        htmlEmail.setHostName(hostname);
        htmlEmail.setAuthentication(username, password);

        if (sslSupport){
            htmlEmail.setSSLOnConnect(sslSupport);
            htmlEmail.setSslSmtpPort(sslSmtpPort);
        }else{
            htmlEmail.setSmtpPort(port);
        }

        String code = "done";
        String reason = String.format("成功发送邮件到%s",to);
        try {
            String[] froms = from.split("$");
            if (froms.length == 1) {
                htmlEmail.setFrom(froms[0]);
            } else {
                if (froms.length > 1) {
                    htmlEmail.setFrom(froms[0], froms[1]);
                }
            }

            String[] tos = to.split(";");
            if (tos.length > 0) {
                for (String one : tos) {
                    String[] ones = one.split("$");
                    if (ones.length == 1) {
                        htmlEmail.addTo(ones[0]);
                    } else {
                        if (ones.length > 1) {
                            htmlEmail.addTo(ones[0], ones[1]);
                        }
                    }
                }
            }

            htmlEmail.setSubject(subject);
            htmlEmail.setCharset(encoding);
            htmlEmail.setMsg(content);

            htmlEmail.send();
            log(String.format("Send mail to %s", to));
        } catch (Exception ex) {
            ex.printStackTrace();
            log("Failed to send email,reason=" + ex.getMessage(), "error");
            code = "failed";
            reason = String.format("发送邮件失败,邮箱:%s",to);
        }finally{
            ctx.SetValue(codeId,code);
            ctx.SetValue(reasonId,reason);
        }
    }
}
